home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PutAwayVolumes.c
-
- Description:This code sample demonstrates several ways to unmount a volume.
- [1] Call MoreFiles and have it take its best shot.
- [2] Augment MoreFiles with a little Finder-style interface
- and some strategic trash-emptying.
- [3] Send an AppleEvent to Finder and have it do the whole thing.
-
- A real strategy might use all of the above. Basically, the problem is
- this: although UnmountVol has been patched so that some commonly open
- files (mostly having to do with desktop info) are closed before the
- volume unmounts, not all are, and in particular files associated
- with the trash on shared volumes are not automagically closed.
-
- Each of the three above-mentioned methods has its flaws.
-
- [1] It wouldn't be in the spirit of MoreFiles to empty
- the trash silently when attempting to unmount, so it's
- not surprising MoreFiles doesn't do it.
-
- [2] Getting confirmation from the user involves posting an
- alert, which is not always easy for non-apps.
-
- [3] Requires the unmounter to send AppleEvents, which is
- not always easy for non-apps, and may require user to
- switch to Finder to confirm alerts, which also is not
- always easy for non-apps.
-
- Your program may have to combine methods to achieve the effect it
- needs. And your program should be ready for the methods to fail --
- not that you should expect a proper implementation to fail, but
- your program shouldn't assume that it will not.
-
- Of course, if some application other than Finder or At Ease has files
- open on the volume, the volume simply will not unmount, and that's a
- legitimate error condition.
-
- Note this sample in its current state will unmount all AppleShare
- volumes. The interesting function is PutAwayOneVolume, and it has
- nothing to do with AppleShare in particular. The rest of the functions
- are here simply to drive PutAwayOneVolume.
-
- Author: PG
-
- Copyright: Copyright: © 1996-1999 by Apple Computer, Inc.
- all rights reserved.
-
- Disclaimer: You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
-
- Change History (most recent first):
- 6/25/99 Updated for Metrowerks Codewarror Pro 2.1(KG)
-
- 03/20/96 St. Luther points out that 'hpbp->volumeParam.ioVFSID'
- is not a sufficient test for AppleShare; check the driver
- name instead; this makes the sample a little more accurate
- but a little less useful, since nobody specifies volumes
- by driver name. However, the portion of this code which
- cares about which volumes to unmount is only here to make
- the sample run anyway; users will have to adapt this code
- regardless; PutAwayOneVolume is the interesting code, and
- it's not affected by this change.(PG)
-
- 03/20/96 PutAwayVolumes doesn't really need to know the names of the
- volumes it's indexing. Save some stack.(PG)
-
- 03/21/96 Use MoreFiles version of UnmountAndEject. Keeping my own
- copy was just stupid, especially since I plan to use more
- of MoreFiles.(PG)
-
- 03/21/96 After conversation with Jim, realized the AppleEvent
- strategy is not always best. This version makes use of
- semi-documented 'ReleaseFolder' call to deal with shared
- trash folders.(PG)
-
- */
- #define OLDROUTINELOCATIONS 0
- #define OLDROUTINENAMES 0
- #define SystemSevenOrLater 1
-
- #ifndef __FILES__
- # include <Files.h>
- #endif
-
- #ifndef __LOWMEM__
- # include <LowMem.h>
- #endif
-
- #ifndef __DEVICES__
- # include <Devices.h>
- #endif
-
- #ifndef __PLSTRINGFUNCS__
- # include <PLStringFuncs.h>
- #endif
-
- #ifndef __PROCESSES__
- # include <Processes.h>
- #endif
- #ifndef __DIALOGS__
- # include <Dialogs.h>
- #endif
- #include "PutAwayOneVolume.h"
-
- #define USE_INTERNAL_CODE 1
-
- //
- // USE_INTERNAL_CODE controls whether we send the AppleEvent to Finder
- // or use the internal code to unmount the volume ('ReleaseFolder').
- //
-
- enum
- {
- kCreatorCode_Finder = 'MACS',
- kCreatorCode_AtEase = 'mfdr'
- };
-
- static pascal OSErr GetCreatorOfFinderLikeProcess (OSType *processSignature)
- {
- OSErr err = noErr;
-
- #if !USE_INTERNAL_CODE
-
- ProcessSerialNumber psn = { kNoProcess, kNoProcess };
- ProcessInfoRec pir = { sizeof (pir), nil };
-
- #endif
-
- *processSignature = 0;
-
- #if !USE_INTERNAL_CODE
-
- pir.processAppSpec = nil;
-
- for (;;)
- {
- err = GetNextProcess (&psn);
- if (err)
- {
- if (err == procNotFound) err = noErr;
- break;
- }
-
- err = GetProcessInformation (&psn,&pir);
- if (err) break;
-
- if (pir.processSignature == kCreatorCode_Finder || pir.processSignature == kCreatorCode_AtEase)
- {
- *processSignature = pir.processSignature;
- break;
- }
- }
-
- #endif
-
- return err;
- }
-
- static pascal Boolean VolDriverNameIs (short vRefNum, ConstStr255Param potentialDriverName)
- {
- Boolean result = false;
-
- const VCB *vcbQueueScanner = (const VCB *) GetVCBQHdr ( )->qHead;
-
- while (vcbQueueScanner)
- {
- if (vcbQueueScanner->vcbVRefNum == vRefNum)
- {
- short csParam [11];
-
- if (!Status (vcbQueueScanner->vcbDRefNum,1,csParam))
- {
- DCtlHandle dCtlHandle = *(DCtlHandle *) csParam;
- DRVRHeaderPtr drvrHeaderPtr = (DRVRHeaderPtr) (**dCtlHandle).dCtlDriver;
- Boolean isHandle = (**dCtlHandle).dCtlFlags & dRAMBasedMask;
- ConstStr255Param drvrName = drvrHeaderPtr->drvrName;
- SInt8 hState;
-
- //
- // We lock the driver handle temporarily in case
- // <PLStringFuncs.glue.lib> (which contains
- // the implementation of PLstrcmp) lives in
- // another (potentially unloaded) code segment.
- //
-
- if (isHandle)
- {
- hState = HGetState ((Handle) drvrHeaderPtr);
- HLock ((Handle) drvrHeaderPtr);
- drvrName = (**(DRVRHeaderHandle)drvrHeaderPtr).drvrName;
- }
-
- result = !PLstrcmp (potentialDriverName,drvrName);
-
- if (isHandle)
- HSetState ((Handle) drvrHeaderPtr, hState);
- }
- }
-
- vcbQueueScanner = (const VCB *) (vcbQueueScanner->qLink);
- }
-
- return result;
- }
-
- static pascal OSErr PutAwayVolumes (const unsigned char *driverName)
- {
- OSErr err = noErr;
-
- OSType finderLikeProcess;
-
- if (!(err = GetCreatorOfFinderLikeProcess (&finderLikeProcess)))
- {
- HParmBlkPtr hpbp = (HParmBlkPtr) NewPtrClear (sizeof (*hpbp));
- if (!(err = MemError ( )))
- {
- hpbp->volumeParam.ioVolIndex = 1;
-
- for (;;)
- {
- err = PBHGetVInfoSync (hpbp);
- if (err)
- {
- if (err == nsvErr) err = noErr;
- break;
- }
-
- if (VolDriverNameIs (hpbp->volumeParam.ioVRefNum, driverName))
- {
- err = PutAwayOneVolume (hpbp->volumeParam.ioVRefNum, finderLikeProcess);
- if (err) break;
- }
-
- hpbp->volumeParam.ioVolIndex += 1;
- }
-
- DisposePtr ((Ptr) hpbp);
- if (!err) err = MemError ( );
- }
- }
-
- return err;
- }
-
- void main (void)
- {
- MaxApplZone ( );
- InitGraf (&(qd.thePort));
- InitFonts ( );
- InitWindows ( );
- InitMenus ( );
- TEInit ( );
- InitDialogs (nil);
-
- // (void) PutAwayVolumes ("\p.Sony");
-
- (void) PutAwayVolumes ("\p.AFPTranslator");
- }